<!DOCTYPE html>
<!--
Copyright (c) 2015 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="/tracing/base/math/range.html">
<link rel="import" href="/tracing/core/test_utils.html">
<link rel="import" href="/tracing/ui/tracks/chart_point.html">
<link rel="import" href="/tracing/ui/tracks/chart_series.html">
<link rel="import" href="/tracing/ui/tracks/chart_series_y_axis.html">

<script>
'use strict';

tr.b.unittest.testSuite(function() {
  const ChartSeriesYAxis = tr.ui.tracks.ChartSeriesYAxis;
  const ChartPoint = tr.ui.tracks.ChartPoint;
  const ChartSeries = tr.ui.tracks.ChartSeries;
  const Range = tr.b.math.Range;

  function buildRange() {
    const range = new Range();
    for (let i = 0; i < arguments.length; i++) {
      range.addValue(arguments[i]);
    }
    return range;
  }

  function buildSeries() {
    const points = [];
    for (let i = 0; i < arguments.length; i++) {
      points.push(new ChartPoint(undefined, i, arguments[i]));
    }
    return new ChartSeries(points, new ChartSeriesYAxis());
  }

  test('instantiate_emptyBounds', function() {
    const seriesYAxis = new ChartSeriesYAxis();
    assert.isTrue(seriesYAxis.bounds.isEmpty);
  });

  test('instantiate_nonEmptyBounds', function() {
    const seriesYAxis = new ChartSeriesYAxis(-2, 12);
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, -2);
    assert.strictEqual(seriesYAxis.bounds.max, 12);
  });

  test('instantiate_equalBounds', function() {
    const seriesYAxis = new ChartSeriesYAxis(2.72);
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 2.72);
    assert.strictEqual(seriesYAxis.bounds.max, 2.72);
  });

  test('checkValueToUnitRange_emptyBounds', function() {
    const seriesYAxis = new ChartSeriesYAxis();
    assert.throws(function() { seriesYAxis.valueToUnitRange(42); });
  });

  test('checkValueToUnitRange_nonEmptyBounds', function() {
    const seriesYAxis = new ChartSeriesYAxis(10, 20);

    assert.strictEqual(seriesYAxis.valueToUnitRange(0), -1);
    assert.strictEqual(seriesYAxis.valueToUnitRange(10), 0);
    assert.strictEqual(seriesYAxis.valueToUnitRange(15), 0.5);
    assert.strictEqual(seriesYAxis.valueToUnitRange(20), 1);
    assert.strictEqual(seriesYAxis.valueToUnitRange(30), 2);
  });

  test('checkValueToUnitRange_equalBounds', function() {
    const seriesYAxis = new ChartSeriesYAxis(3.14);

    assert.strictEqual(seriesYAxis.valueToUnitRange(0), 0);
    assert.strictEqual(seriesYAxis.valueToUnitRange(3.14), 0);
    assert.strictEqual(seriesYAxis.valueToUnitRange(6.28), 0);
  });

  test('checkAutoSetFromRange_emptyBounds', function() {
    // Empty range.
    let seriesYAxis = new ChartSeriesYAxis();
    seriesYAxis.autoSetFromRange(buildRange());
    assert.isTrue(seriesYAxis.bounds.isEmpty);

    // Non-empty range.
    seriesYAxis = new ChartSeriesYAxis();
    seriesYAxis.autoSetFromRange(buildRange(-1, 3));
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, -1);
    assert.strictEqual(seriesYAxis.bounds.max, 3);
  });

  test('checkAutoSetFromRange_nonEmptyBounds', function() {
    // Empty range.
    let seriesYAxis = new ChartSeriesYAxis(0, 1);
    seriesYAxis.autoSetFromRange(buildRange());
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 0);
    assert.strictEqual(seriesYAxis.bounds.max, 1);

    // No configuration.
    seriesYAxis = new ChartSeriesYAxis(2, 3);
    seriesYAxis.autoSetFromRange(buildRange(1, 4));
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 2);
    assert.strictEqual(seriesYAxis.bounds.max, 3);

    // Allow expanding min.
    seriesYAxis = new ChartSeriesYAxis(-2, -1);
    seriesYAxis.autoSetFromRange(buildRange(-3, 0), {expandMin: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, -3);
    assert.strictEqual(seriesYAxis.bounds.max, -1);

    // Allow shrinking min.
    seriesYAxis = new ChartSeriesYAxis(-2, -1);
    seriesYAxis.autoSetFromRange(buildRange(-1.5, 0.5), {shrinkMin: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, -1.5);
    assert.strictEqual(seriesYAxis.bounds.max, -1);

    seriesYAxis = new ChartSeriesYAxis(7, 8);
    seriesYAxis.autoSetFromRange(buildRange(9, 10), {shrinkMin: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 8);
    assert.strictEqual(seriesYAxis.bounds.max, 8);

    // Allow expanding max.
    seriesYAxis = new ChartSeriesYAxis(19, 20);
    seriesYAxis.autoSetFromRange(buildRange(18, 21), {expandMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 19);
    assert.strictEqual(seriesYAxis.bounds.max, 21);

    // Allow shrinking max.
    seriesYAxis = new ChartSeriesYAxis(30, 32);
    seriesYAxis.autoSetFromRange(buildRange(29, 31), {shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 30);
    assert.strictEqual(seriesYAxis.bounds.max, 31);

    seriesYAxis = new ChartSeriesYAxis(41, 42);
    seriesYAxis.autoSetFromRange(buildRange(39, 40), {shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 41);
    assert.strictEqual(seriesYAxis.bounds.max, 41);

    // Allow shrinking both bounds.
    seriesYAxis = new ChartSeriesYAxis(50, 53);
    seriesYAxis.autoSetFromRange(buildRange(51, 52),
        {shrinkMin: true, shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 51);
    assert.strictEqual(seriesYAxis.bounds.max, 52);

    seriesYAxis = new ChartSeriesYAxis(50, 53);
    seriesYAxis.autoSetFromRange(buildRange(49, 52),
        {shrinkMin: true, shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 50);
    assert.strictEqual(seriesYAxis.bounds.max, 52);

    seriesYAxis = new ChartSeriesYAxis(50, 53);
    seriesYAxis.autoSetFromRange(buildRange(51, 54),
        {shrinkMin: true, shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 51);
    assert.strictEqual(seriesYAxis.bounds.max, 53);

    seriesYAxis = new ChartSeriesYAxis(50, 53);
    seriesYAxis.autoSetFromRange(buildRange(49, 54),
        {shrinkMin: true, shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 50);
    assert.strictEqual(seriesYAxis.bounds.max, 53);

    // Allow expanding both bounds.
    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(0, 100),
        {expandMin: true, expandMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 0);
    assert.strictEqual(seriesYAxis.bounds.max, 100);

    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(60.5, 100),
        {expandMin: true, expandMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 60);
    assert.strictEqual(seriesYAxis.bounds.max, 100);

    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(0, 60.5),
        {expandMin: true, expandMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 0);
    assert.strictEqual(seriesYAxis.bounds.max, 61);

    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(60.2, 60.8),
        {expandMin: true, expandMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 60);
    assert.strictEqual(seriesYAxis.bounds.max, 61);

    // Allow shrinking min and expanding max.
    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(62, 63),
        {shrinkMin: true, expandMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 62);
    assert.strictEqual(seriesYAxis.bounds.max, 63);

    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(59, 63),
        {shrinkMin: true, expandMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 60);
    assert.strictEqual(seriesYAxis.bounds.max, 63);

    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(60.2, 60.8),
        {shrinkMin: true, expandMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 60.2);
    assert.strictEqual(seriesYAxis.bounds.max, 61);

    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(59, 60.5),
        {shrinkMin: true, expandMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 60);
    assert.strictEqual(seriesYAxis.bounds.max, 61);

    // Allow expanding min and shrinking max.
    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(62, 63),
        {expandMin: true, shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 60);
    assert.strictEqual(seriesYAxis.bounds.max, 61);

    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(59, 63),
        {expandMin: true, shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 59);
    assert.strictEqual(seriesYAxis.bounds.max, 61);

    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(60.2, 60.8),
        {expandMin: true, shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 60);
    assert.strictEqual(seriesYAxis.bounds.max, 60.8);

    seriesYAxis = new ChartSeriesYAxis(60, 61);
    seriesYAxis.autoSetFromRange(buildRange(59, 60.5),
        {expandMin: true, shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 59);
    assert.strictEqual(seriesYAxis.bounds.max, 60.5);

    // Allow everything.
    seriesYAxis = new ChartSeriesYAxis(200, 250);
    seriesYAxis.autoSetFromRange(buildRange(150, 175),
        {expandMin: true, expandMax: true, shrinkMin: true, shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 150);
    assert.strictEqual(seriesYAxis.bounds.max, 175);

    seriesYAxis = new ChartSeriesYAxis(0, 0.1);
    seriesYAxis.autoSetFromRange(buildRange(0.2, 0.3),
        {expandMin: true, expandMax: true, shrinkMin: true, shrinkMax: true});
    assert.isFalse(seriesYAxis.bounds.isEmpty);
    assert.strictEqual(seriesYAxis.bounds.min, 0.2);
    assert.strictEqual(seriesYAxis.bounds.max, 0.3);
  });

  test('checkAutoSetFromSeries_noSeries', function() {
    const seriesYAxis = new ChartSeriesYAxis(-100, 100);
    const series = [];

    seriesYAxis.autoSetFromSeries(series);
    assert.strictEqual(seriesYAxis.bounds.min, -100);
    assert.strictEqual(seriesYAxis.bounds.max, 100);
  });

  test('checkAutoSetFromSeries_oneSeries', function() {
    const seriesYAxis = new ChartSeriesYAxis(-100, 100);
    const series = [buildSeries(-80, 100, -40, 200)];

    seriesYAxis.autoSetFromSeries(series, {shrinkMin: true, expandMax: true});
    assert.strictEqual(seriesYAxis.bounds.min, -80);
    assert.strictEqual(seriesYAxis.bounds.max, 200);
  });

  test('checkAutoSetFromSeries_multipleSeries', function() {
    const seriesYAxis = new ChartSeriesYAxis(-100, 100);
    const series = [
      buildSeries(0, 20, 10, 30),
      buildSeries(),
      buildSeries(-500)
    ];

    seriesYAxis.autoSetFromSeries(series, {expandMin: true, shrinkMax: true});
    assert.strictEqual(seriesYAxis.bounds.min, -500);
    assert.strictEqual(seriesYAxis.bounds.max, 30);
  });
});
</script>
